package com.theten52.demo.io.s2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 实现一个简单的 Socket，服务器端只发给客户端信息，再由客户端打印出来的例子，代码如下：
 * <p>
 * 调用 accept 方法，阻塞等待客户端连接；
 * 利用 Socket 模拟了一个简单的客户端，只进行连接、读取和打印；
 * 在 Java 中，线程的实现是比较重量级的，所以线程的启动或者销毁是很消耗服务器的资源的，即使使用线程池来实现。
 * 使用上述传统的 Socket 方式，当连接数极具上升也会带来性能瓶颈，原因是线程的上线文切换开销会在高并发的时候体现的很明显，
 * 并且以上操作方式还是同步阻塞式的编程，性能问题在高并发的时候就会体现的尤为明显。
 *
 * @author wangjin
 * @date 2021/3/11
 */
public class BIOSocketDemo {
    public static void main(String[] args) throws InterruptedException {
        int port = 9987;
        //端口号
        // Socket 服务器端（简单的发送信息）
        //noinspection AlibabaAvoidManuallyCreateThread
        Thread sThread = new Thread(() -> {
            try {
                ServerSocket serverSocket = new ServerSocket(port);
                while (true) {
                    // 等待连接
                    System.out.println("服务器等待连接。。。");
                    Socket socket = serverSocket.accept();
                    System.out.println("连接成功，回写数据。。。");
                    Thread sHandlerThread = new Thread(() -> {
                        try (PrintWriter printWriter = new PrintWriter(socket.getOutputStream())) {
                            printWriter.println("hello world！");
                            printWriter.flush();
                            System.exit(0);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
                    sHandlerThread.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        sThread.start();

        Thread.sleep(1000L);

        // Socket 客户端（接收信息并打印）
        System.out.println("客户端开始连接");
        try (Socket cSocket = new Socket("localhost", port)) {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
            bufferedReader.lines().forEach(s -> System.out.println("客户端：" + s));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
